make terracotta compatible with python 3.13#364
Conversation
setup.cfg
Outdated
| ignore::pytest.PytestUnraisableExceptionWarning | ||
| ignore:.*socket\.socket.* |
There was a problem hiding this comment.
Can you help me out on this? It passed with 3.12 the way it was, but for 3.13 this change was needed. But I believe this now ignores more than before, which is not a good thing...
There was a problem hiding this comment.
What was warning being raised?
There was a problem hiding this comment.
That's what we are getting, which should be ignored by this (or probably cleaned up) but so far everything looks good - all connect seem to use a context manager...
=================================================================================== FAILURES ===================================================================================
______________________________________________________________________________ test_where[mysql] _______________________________________________________________________________
cls = <class '_pytest.runner.CallInfo'>, func = <function call_and_report.<locals>.<lambda> at 0x78ee0b2351c0>, when = 'call'
reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)
@classmethod
def from_call(
cls,
func: Callable[[], TResult],
when: Literal["collect", "setup", "call", "teardown"],
reraise: type[BaseException] | tuple[type[BaseException], ...] | None = None,
) -> CallInfo[TResult]:
"""Call func, wrapping the result in a CallInfo.
:param func:
The function to call. Called without arguments.
:type func: Callable[[], _pytest.runner.TResult]
:param when:
The phase in which the function is called.
:param reraise:
Exception or exceptions that shall propagate if raised by the
function, instead of being wrapped in the CallInfo.
"""
excinfo = None
start = timing.time()
precise_start = timing.perf_counter()
try:
> result: TResult | None = func()
venv/lib/python3.13/site-packages/_pytest/runner.py:341:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
venv/lib/python3.13/site-packages/_pytest/runner.py:242: in <lambda>
lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
venv/lib/python3.13/site-packages/pluggy/_hooks.py:513: in __call__
return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
venv/lib/python3.13/site-packages/pluggy/_manager.py:120: in _hookexec
return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
venv/lib/python3.13/site-packages/_pytest/threadexception.py:92: in pytest_runtest_call
yield from thread_exception_runtest_hook()
venv/lib/python3.13/site-packages/_pytest/threadexception.py:68: in thread_exception_runtest_hook
yield
venv/lib/python3.13/site-packages/_pytest/unraisableexception.py:95: in pytest_runtest_call
yield from unraisable_exception_runtest_hook()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
def unraisable_exception_runtest_hook() -> Generator[None]:
with catch_unraisable_exception() as cm:
try:
yield
finally:
if cm.unraisable:
if cm.unraisable.err_msg is not None:
err_msg = cm.unraisable.err_msg
else:
err_msg = "Exception ignored in"
msg = f"{err_msg}: {cm.unraisable.object!r}\n\n"
msg += "".join(
traceback.format_exception(
cm.unraisable.exc_type,
cm.unraisable.exc_value,
cm.unraisable.exc_traceback,
)
)
> warnings.warn(pytest.PytestUnraisableExceptionWarning(msg))
E pytest.PytestUnraisableExceptionWarning: Exception ignored in: <sqlite3.Connection object at 0x78ee0bde5e40>
E
E Traceback (most recent call last):
E File "/home/kittnjdr/workspace/terracotta/venv/lib/python3.13/site-packages/sqlalchemy/engine/base.py", line 1964, in _exec_single_context
E self.dialect.do_execute(
E ~~~~~~~~~~~~~~~~~~~~~~~^
E cursor, str_statement, effective_parameters, context
E ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E )
E ^
E File "/home/kittnjdr/workspace/terracotta/venv/lib/python3.13/site-packages/sqlalchemy/engine/default.py", line 945, in do_execute
E cursor.execute(statement, parameters)
E ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
E File "/home/kittnjdr/workspace/terracotta/venv/lib/python3.13/site-packages/pymysql/cursors.py", line 153, in execute
E result = self._query(query)
E File "/home/kittnjdr/workspace/terracotta/venv/lib/python3.13/site-packages/pymysql/cursors.py", line 322, in _query
E conn.query(q)
E ~~~~~~~~~~^^^
E File "/home/kittnjdr/workspace/terracotta/venv/lib/python3.13/site-packages/pymysql/connections.py", line 563, in query
E self._affected_rows = self._read_query_result(unbuffered=unbuffered)
E ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
E File "/home/kittnjdr/workspace/terracotta/venv/lib/python3.13/site-packages/pymysql/connections.py", line 825, in _read_query_result
E result.read()
E ~~~~~~~~~~~^^
E File "/home/kittnjdr/workspace/terracotta/venv/lib/python3.13/site-packages/pymysql/connections.py", line 1199, in read
E first_packet = self.connection._read_packet()
E File "/home/kittnjdr/workspace/terracotta/venv/lib/python3.13/site-packages/pymysql/connections.py", line 775, in _read_packet
E packet.raise_for_error()
E ~~~~~~~~~~~~~~~~~~~~~~^^
E File "/home/kittnjdr/workspace/terracotta/venv/lib/python3.13/site-packages/pymysql/protocol.py", line 219, in raise_for_error
E err.raise_mysql_exception(self._data)
E ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
E File "/home/kittnjdr/workspace/terracotta/venv/lib/python3.13/site-packages/pymysql/err.py", line 150, in raise_mysql_exception
E raise errorclass(errno, errval)
E pymysql.err.ProgrammingError: (1146, "Table 'flprauxwowkvktrdhwtiidkx.key_names' doesn't exist")
E
E During handling of the above exception, another exception occurred:
E
E Traceback (most recent call last):
E File "/home/kittnjdr/workspace/terracotta/venv/lib/python3.13/site-packages/sqlalchemy/engine/base.py", line 2222, in _handle_dbapi_exception
E def _handle_dbapi_exception(
E
E ResourceWarning: unclosed database in <sqlite3.Connection object at 0x78ee0bde5e40>
venv/lib/python3.13/site-packages/_pytest/unraisableexception.py:85: PytestUnraisableExceptionWarning
There was a problem hiding this comment.
Wow, that's really weird.
Table 'flprauxwowkvktrdhwtiidkx.key_names' doesn't exist
Why would an error like this be unraisable...?
There was a problem hiding this comment.
Unless we have a good idea as to why this happens, let's ignore it selectively – that is, something like this:
ignore:pymysql.err.ProgrammingError:pytest.PytestUnraisableExceptionWarning
There was a problem hiding this comment.
The issue lies deeper, I believe. I also get this for sqlite, but only sometimes. So this could be many things. The connect method not closing properly or the engine not being disposed properly? I tried defining __del__ for the class disposing the engine, that reduced the number of warnings, but still did not fix all of them.
that's why we unfortunately would have to keep the more generic ignore...
Not sure how to solve that - maybe using sessions might fix that?
There was a problem hiding this comment.
Are the warnings you're seeing all the same or are some different to what you posted above?
(I can't reproduce this locally rn since I don't have a working MySQL install)
There was a problem hiding this comment.
I just ran the dbs in docker compose:
services:
mysql:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: root
ports:
- 127.0.0.1:3306:3306
postgres:
image: postgres
environment:
POSTGRES_USER: root
POSTGRES_PASSWORD: root
ports:
- 127.0.0.1:5432:5432The full output I get is this:
errors
======================================================================================================================= ERRORS ========================================================================================================================
_______________________________________________________________________________________________ ERROR at setup of test_non_writable_lazy_loading[mysql] _______________________________________________________________________________________________
cls = <class '_pytest.runner.CallInfo'>, func = <function call_and_report.<locals>.<lambda> at 0x7dbb3ba3fb00>, when = 'setup', reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)
@classmethod
def from_call(
cls,
func: Callable[[], TResult],
when: Literal["collect", "setup", "call", "teardown"],
reraise: type[BaseException] | tuple[type[BaseException], ...] | None = None,
) -> CallInfo[TResult]:
"""Call func, wrapping the result in a CallInfo.
:param func:
The function to call. Called without arguments.
:type func: Callable[[], _pytest.runner.TResult]
:param when:
The phase in which the function is called.
:param reraise:
Exception or exceptions that shall propagate if raised by the
function, instead of being wrapped in the CallInfo.
"""
excinfo = None
start = timing.time()
precise_start = timing.perf_counter()
try:
> result: TResult | None = func()
venv/lib/python3.13/site-packages/_pytest/runner.py:341:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
venv/lib/python3.13/site-packages/_pytest/runner.py:242: in <lambda>
lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
venv/lib/python3.13/site-packages/pluggy/_hooks.py:513: in __call__
return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
venv/lib/python3.13/site-packages/pluggy/_manager.py:120: in _hookexec
return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
venv/lib/python3.13/site-packages/_pytest/unraisableexception.py:90: in pytest_runtest_setup
yield from unraisable_exception_runtest_hook()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
def unraisable_exception_runtest_hook() -> Generator[None]:
with catch_unraisable_exception() as cm:
try:
yield
finally:
if cm.unraisable:
if cm.unraisable.err_msg is not None:
err_msg = cm.unraisable.err_msg
else:
err_msg = "Exception ignored in"
msg = f"{err_msg}: {cm.unraisable.object!r}\n\n"
msg += "".join(
traceback.format_exception(
cm.unraisable.exc_type,
cm.unraisable.exc_value,
cm.unraisable.exc_traceback,
)
)
> warnings.warn(pytest.PytestUnraisableExceptionWarning(msg))
E pytest.PytestUnraisableExceptionWarning: Exception ignored in: <sqlite3.Connection object at 0x7dbb32596b60>
E
E Traceback (most recent call last):
E File "/home/kittnjdr/workspace/terracotta/venv/lib/python3.13/site-packages/sqlalchemy/util/langhelpers.py", line 1318, in oneshot
E def oneshot(*args, **kw):
E
E ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb32596b60>
venv/lib/python3.13/site-packages/_pytest/unraisableexception.py:85: PytestUnraisableExceptionWarning
====================================================================================================================== FAILURES =======================================================================================================================
_____________________________________________________________________________________________________________ test_path_override[sqlite] ______________________________________________________________________________________________________________
cls = <class '_pytest.runner.CallInfo'>, func = <function call_and_report.<locals>.<lambda> at 0x7dbb325d60c0>, when = 'call', reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)
@classmethod
def from_call(
cls,
func: Callable[[], TResult],
when: Literal["collect", "setup", "call", "teardown"],
reraise: type[BaseException] | tuple[type[BaseException], ...] | None = None,
) -> CallInfo[TResult]:
"""Call func, wrapping the result in a CallInfo.
:param func:
The function to call. Called without arguments.
:type func: Callable[[], _pytest.runner.TResult]
:param when:
The phase in which the function is called.
:param reraise:
Exception or exceptions that shall propagate if raised by the
function, instead of being wrapped in the CallInfo.
"""
excinfo = None
start = timing.time()
precise_start = timing.perf_counter()
try:
> result: TResult | None = func()
venv/lib/python3.13/site-packages/_pytest/runner.py:341:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
venv/lib/python3.13/site-packages/_pytest/runner.py:242: in <lambda>
lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
venv/lib/python3.13/site-packages/pluggy/_hooks.py:513: in __call__
return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
venv/lib/python3.13/site-packages/pluggy/_manager.py:120: in _hookexec
return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
venv/lib/python3.13/site-packages/_pytest/threadexception.py:92: in pytest_runtest_call
yield from thread_exception_runtest_hook()
venv/lib/python3.13/site-packages/_pytest/threadexception.py:68: in thread_exception_runtest_hook
yield
venv/lib/python3.13/site-packages/_pytest/unraisableexception.py:95: in pytest_runtest_call
yield from unraisable_exception_runtest_hook()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
def unraisable_exception_runtest_hook() -> Generator[None]:
with catch_unraisable_exception() as cm:
try:
yield
finally:
if cm.unraisable:
if cm.unraisable.err_msg is not None:
err_msg = cm.unraisable.err_msg
else:
err_msg = "Exception ignored in"
msg = f"{err_msg}: {cm.unraisable.object!r}\n\n"
msg += "".join(
traceback.format_exception(
cm.unraisable.exc_type,
cm.unraisable.exc_value,
cm.unraisable.exc_traceback,
)
)
> warnings.warn(pytest.PytestUnraisableExceptionWarning(msg))
E pytest.PytestUnraisableExceptionWarning: Exception ignored in: <sqlite3.Connection object at 0x7dbb323d45e0>
E
E Traceback (most recent call last):
E File "/home/kittnjdr/workspace/terracotta/venv/lib/python3.13/site-packages/sqlalchemy/sql/schema.py", line 5060, in columns_autoinc_first
E @property
E
E ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb323d45e0>
venv/lib/python3.13/site-packages/_pytest/unraisableexception.py:85: PytestUnraisableExceptionWarning
=============================================================================================================== short test summary info ===============================================================================================================
FAILED tests/drivers/test_raster_drivers.py::test_path_override[sqlite] - pytest.PytestUnraisableExceptionWarning: Exception ignored in: <sqlite3.Connection object at 0x7dbb323d45e0>
ERROR tests/drivers/test_raster_drivers.py::test_non_writable_lazy_loading[mysql] - pytest.PytestUnraisableExceptionWarning: Exception ignored in: <sqlite3.Connection object at 0x7dbb32596b60>
======================================================================================================= 1 failed, 122 passed, 1 error in 37.28s =======================================================================================================
Exception ignored in: <sqlite3.Connection object at 0x7dbb32595f30>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb32595f30>
Exception ignored in: <sqlite3.Connection object at 0x7dbb32449a80>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb32449a80>
Exception ignored in: <sqlite3.Connection object at 0x7dbb323d4400>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb323d4400>
Exception ignored in: <sqlite3.Connection object at 0x7dbb323d6020>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb323d6020>
Exception ignored in: <sqlite3.Connection object at 0x7dbb323d4d60>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb323d4d60>
Exception ignored in: <sqlite3.Connection object at 0x7dbb323d5300>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb323d5300>
Exception ignored in: <sqlite3.Connection object at 0x7dbb32448040>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb32448040>
Exception ignored in: <sqlite3.Connection object at 0x7dbb324498a0>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb324498a0>
Exception ignored in: <sqlite3.Connection object at 0x7dbb324486d0>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb324486d0>
Exception ignored in: <sqlite3.Connection object at 0x7dbb32be7e20>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb32be7e20>
Exception ignored in: <sqlite3.Connection object at 0x7dbb32be73d0>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb32be73d0>
Exception ignored in: <sqlite3.Connection object at 0x7dbb3382e6b0>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb3382e6b0>
Exception ignored in: <sqlite3.Connection object at 0x7dbb325956c0>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb325956c0>
Exception ignored in: <sqlite3.Connection object at 0x7dbb32595210>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb32595210>
Exception ignored in: <sqlite3.Connection object at 0x7dbb32595990>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb32595990>
Exception ignored in: <sqlite3.Connection object at 0x7dbb3244bb50>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb3244bb50>
Exception ignored in: <sqlite3.Connection object at 0x7dbb32597880>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb32597880>
Exception ignored in: <sqlite3.Connection object at 0x7dbb3247c5e0>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb3247c5e0>
Exception ignored in: <sqlite3.Connection object at 0x7dbb3247e980>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb3247e980>
Exception ignored in: <sqlite3.Connection object at 0x7dbb3247d210>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb3247d210>
Exception ignored in: <sqlite3.Connection object at 0x7dbb3247d4e0>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb3247d4e0>
Exception ignored in: <sqlite3.Connection object at 0x7dbb322a4b80>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb322a4b80>
Exception ignored in: <sqlite3.Connection object at 0x7dbb3247ee30>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb3247ee30>
Exception ignored in: <sqlite3.Connection object at 0x7dbb322a65c0>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb322a65c0>
Exception ignored in: <sqlite3.Connection object at 0x7dbb3b1a06d0>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb3b1a06d0>
Exception ignored in: <sqlite3.Connection object at 0x7dbb3b1a0d60>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb3b1a0d60>
Exception ignored in: <sqlite3.Connection object at 0x7dbb323d6c50>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb323d6c50>
Exception ignored in: <sqlite3.Connection object at 0x7dbb322a5030>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb322a5030>
Exception ignored in: <sqlite3.Connection object at 0x7dbb3a0d9b70>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb3a0d9b70>
Exception ignored in: <sqlite3.Connection object at 0x7dbb3a0d9c60>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb3a0d9c60>
Exception ignored in: <sqlite3.Connection object at 0x7dbb3b1a1a80>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb3b1a1a80>
Exception ignored in: <sqlite3.Connection object at 0x7dbb3b1a1c60>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb3b1a1c60>
Exception ignored in: <sqlite3.Connection object at 0x7dbb31618d60>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb31618d60>
Exception ignored in: <sqlite3.Connection object at 0x7dbb31618c70>
ResourceWarning: unclosed database in <sqlite3.Connection object at 0x7dbb31618c70This is very inconsistent and it's not always the same (number of) tests that fail or throw the warning. If you only run parts of the test suite, the errors/warnings change or become more frequent. If you add test randomization e.g. using randomly everything breaks so in addition, there is some test pollution going on as well...
Could resource warnings also be some multi-processing/race condition issue?
so IMO the only way forward to at least make it work for 3.13 is ignoring these warnings for now and in the long term try to find the test pollution that are likely caused by the database state not being reset for each test.
There was a problem hiding this comment.
Thanks, I can reproduce it now. No luck with isolating this issue though, so I opted to ignore that specific warning, which also seems to be what other projects do. I suspect this is an issue somewhere within the bowels of SQLAlchemy, since we at no point interact directly with sqlite3.
Not closing a SQLite database should be pretty benign to begin with so I think we're okay for now.
There was a problem hiding this comment.
Ah, that's good to see that others have the same issue. I am fine with ignoring this for now and will subscribe to the other issue - maybe it can be resolved one way or another 👍
|
Thanks @jkittner ! |
The
typing.ionamespace was removed in 3.13